package de.mmis.core.base.util;

import java.util.Collection;
import java.util.Collections;
import java.util.Vector;

import de.mmis.core.base.DeserializableAnnotations.ConstructorDeserializable;
import de.mmis.core.base.DeserializableAnnotations.DeserializationConstructor;
import de.mmis.core.base.MethodDescriptor.P;

/**
 * Vector which can distinguish between visible and invisible elements.
 * 
 * @author Daniel Moos
 * @author Martin Nyolt
 * 
 * @param <E>
 *            the type of the objects in this vector
 */
@ConstructorDeserializable(typeIdentifier = "visiblevector")
public class VisibleVector<E> extends Vector<E> {

	private Vector<E> invisible;

	/**
	 * Create an empty vector used for visible and invisible elements.
	 */
	public VisibleVector() {
		super();

		invisible = new Vector<E>();
	}

	@DeserializationConstructor
	public VisibleVector(@P("VisibleVector") Collection<E> vis,
			@P("InvisibleVector") Vector<E> invis) {
		super(vis);

		invisible = invis;
	}

	public Vector<E> getInvisibleVector() {
		return invisible;
	}

	public Collection<E> getVisibleVector() {
		return Collections.list(elements());
	}

	@Override
	public synchronized void removeAllElements() {
		super.removeAllElements();
		invisible.removeAllElements();
	}

	@Override
	public synchronized boolean removeElement(Object obj) {
		return (super.removeElement(obj) || invisible.removeElement(obj));
	}

	/**
	 * Switch an element between to active or inactive.
	 * 
	 * @param e
	 *            the element
	 * @param active
	 *            true when switch element visible
	 */
	public synchronized void setStatus(E e, boolean active) {
		if (active) {
			if (invisible.remove(e))
				add(e);
		} else {
			if (remove(e))
				invisible.add(e);
		}
	}

}
